package com.insta.formation.calendar.manager.impl;


import java.util.Date;

import com.insta.formation.calendar.dao.ICalendarDao;
import com.insta.formation.calendar.manager.ICalendarManager;
import com.insta.formation.calendar.model.Calendar;
import com.insta.formation.calendar.model.Event;
import com.insta.formation.calendar.model.Person;

public class CalendarManagerImpl implements ICalendarManager
{
	private ICalendarDao calendarDao;

	public CalendarManagerImpl(ICalendarDao calendarDao) {
		this.calendarDao = calendarDao;
	}

	/**
	 *  @See {@link ICalendarManager}
	 */
	public boolean createCalendar(String name, Person owner)
	{
		Calendar cal = new Calendar();
		cal.setName(name);
		cal.setOwner(owner);
		
		return ((this.calendarDao.create(cal) != null) ? true : false);
	}
	
	/**
	 *  @See {@link ICalendarManager}
	 */
	public boolean deleteCalendar(String name, Person owner) {
		Calendar cal = retreiveCalendar(name);
		if ((cal != null) && (isOwner(cal, owner))) {
			calendarDao.delete(cal);
			return true;
		}
		return false;
	}

	/**
	 *  @See {@link ICalendarManager}
	 */
	public Calendar retreiveCalendar(String name) {
		return calendarDao.findByName(name);
	}

	/**
	 *  @See {@link ICalendarManager}
	 */
	public boolean createEvent(String name, Person owner, Event event) {
		Calendar cal = retreiveCalendar(name);
		if ((cal != null) && (isOwner(cal, owner))) {
			
			// deux Event ne peuvent pas avoir le meme nom dans le meme calendrier
			if (getEvent(cal, event.getName()) == null) {
				event.setCreator(owner);
				cal.addEvent(event);
				calendarDao.update(cal);
				return true;
			}
		}
		return false;
	}

	/**
	 *  @See {@link ICalendarManager}
	 */
	public boolean updateEvent(String calendarName, Person owner, String eventName, String newEventName, Date startDate, Date endDate)
	{
		Calendar cal = retreiveCalendar(calendarName);
		
		if ((cal != null) && (isOwner(cal, owner))) {
			Event event =  getEvent(cal, eventName);
			
			// deux Event ne peuvent pas avoir le meme nom dans le meme calendrier
			if ((!eventName.equals(newEventName)) &&
					(getEvent(cal, newEventName) != null)) {
				return false;
			}
			
			if (newEventName != null) {
				event.setName(newEventName);
			}
			if (startDate != null) {
				event.setStartDate(startDate);
			}
			if (endDate != null) {
				event.setEndDate(endDate);
			}
			calendarDao.updateEvent(event);
			return true;
		}
		return false;
	}
	
	/**
	 *  @See {@link ICalendarManager}
	 */
	public boolean deleteEvent(String calName, Person owner, String eventName) {
		
		Calendar cal = retreiveCalendar(calName);
		
		if ((cal != null) && (isOwner(cal, owner))) {
			Event event =  getEvent(cal, eventName);
			
			if (event != null) {
				calendarDao.deleteEvent(cal, event);
				return true;
			}		
		}
		return false;
	}
	
	/**
	 *  @See {@link ICalendarManager}
	 */
	public boolean addEventGuest(Person owner, String calendarName,
			String eventName, Person guest) {
		
		Calendar cal = retreiveCalendar(calendarName);
		if ((cal != null) && (isOwner(cal, owner))) {
			Event event =  getEvent(cal, eventName);
			if (event != null) {
				event.getGuests().add(guest);
				calendarDao.update(cal);
			}
			return true;
		}
		
		return false;
	}

	/**
	 *  @See {@link ICalendarManager}
	 */
	public boolean deleteEventGuest(Person owner, String calendarName,
			String eventName, Person guest) {
		Calendar cal = retreiveCalendar(calendarName);
		if ((cal != null) && (isOwner(cal, owner))) {
			Event event =  getEvent(cal, eventName);
			if ((event != null) && containsGuest(event, guest.getEmail())) {
				
				calendarDao.deleteGuestEvent(event, guest);
				return true;
			}
		}
		return false;
	}
	
	/**
	 *  @See {@link ICalendarManager}
	 */
	public Event visitEvent(String calendarName, String eventName, String emailVisitor)
	{
		Event event = calendarDao.readEvent(calendarName, eventName);
		
		if (event == null) return null;
		
		return containsGuest(event, emailVisitor) ? event : null;
	}
	
	private boolean isOwner(Calendar calendar, Person person) {
		return (person.equals(calendar.getOwner()));
	}
	
	private boolean containsGuest(Event event, String emailVisitor)
	{
		for (Person guest : event.getGuests()) {
			
			if (guest.getEmail().equals(emailVisitor)) {
				return true;
			}
		}
		return false;
	}

	public Event getEvent(Calendar calendar, String eventName)
	{
		Event eventTmp = null;
		for (Event event : calendar.getEvents()) {
			if (event.getName().equals(eventName)) {
				eventTmp = event;
				break;
			}
		}
		return eventTmp;
	}
}
